<template>
  <div class="personal_container">
    <el-card class="personal_card" shadow="hover">
      <template #header>
        <div class="card-header">
          <el-upload
            class="avatar-uploader"
            :action="Upload_API.IMAGE_URL"
            :headers="headerObj"
            :show-file-list="false"
            :on-success="handleAvatarSuccess"
            :before-upload="beforeAvatarUpload"
          >
            <img
              v-if="userFormData.avatar"
              :src="userFormData.avatar"
              class="avatar"
            />
            <el-icon v-else class="avatar-uploader-icon">
              <Plus />
            </el-icon>
          </el-upload>
          <div class="user_info">
            <div class="user_nickname">
              <p>{{ userFormData.name }}</p>
            </div>
            <div class="user_role">
              <p>
                身份:
                <span v-for="item in userFormData.roles">
                  {{ item.name }} &nbsp;
                </span>
              </p>
            </div>
            <div class="user_sign">
              <div style="display: flex; align-items: center">
                个性签名：
                <div
                  style="display: flex; align-items: center"
                  v-if="!isSignEdit"
                >
                  <el-text v-if="userFormData.sign" type="primary">
                    {{ userFormData.sign }}
                  </el-text>
                  <el-text v-else type="primary">
                    这个家伙很懒，什么都没有留下
                  </el-text>
                  <el-icon :size="20" class="sign_edit" @click="openEditSign()">
                    <Edit />
                  </el-icon>
                </div>
                <div style="display: flex" v-else>
                  <el-input
                    v-model="updateSignText"
                    :rows="2"
                    type="textarea"
                    placeholder="Please input"
                  />
                  <el-icon :size="20" class="sign_edit" @click="updateSign()">
                    <CircleCheck />
                  </el-icon>
                  <el-icon
                    :size="20"
                    class="sign_edit"
                    @click="isSignEdit = !isSignEdit"
                  >
                    <CircleClose />
                  </el-icon>
                </div>
              </div>
            </div>
          </div>
        </div>
      </template>
      <el-descriptions
        class="card_descriptions"
        title="基本信息"
        :column="2"
        size="large"
        border
      >
        <el-descriptions-item label-class-name="descriptions_item_label">
          <template #label>
            <div class="cell-item">
              <el-icon>
                <user />
              </el-icon>
              用户名
            </div>
          </template>
          {{ userFormData.username }}
        </el-descriptions-item>
        <el-descriptions-item>
          <template #label>
            <div class="cell-item">
              <svg-icon name="nickname" />
              真实姓名
            </div>
          </template>
          {{ userFormData.name }}
        </el-descriptions-item>
        <el-descriptions-item>
          <template #label>
            <div class="cell-item">
              <svg-icon name="gender" />
              性别
            </div>
          </template>
          <span v-if="userFormData.sex === 1">男性</span>
          <span v-else>女性</span>
        </el-descriptions-item>
        <el-descriptions-item>
          <template #label>
            <div class="cell-item">
              <el-icon>
                <Message />
              </el-icon>
              邮箱
            </div>
          </template>
          {{ userFormData.email }}
        </el-descriptions-item>
        <el-descriptions-item>
          <template #label>
            <div class="cell-item">
              <svg-icon name="userRole" />
              身份
            </div>
          </template>
          <span v-for="item in userFormData.roles">{{ item.name }} &nbsp;</span>
        </el-descriptions-item>
        <el-descriptions-item>
          <template #label>
            <div class="cell-item">
              <el-icon>
                <QuestionFilled />
              </el-icon>
              状态
            </div>
          </template>
          <el-tag type="success" v-if="userFormData.status === 1">正常</el-tag>
          <el-tag tyep="danger" v-else>停用</el-tag>
        </el-descriptions-item>
      </el-descriptions>
      <el-divider />
      <el-descriptions
        class="card_descriptions"
        title="账号设置"
        :column="1"
        size="large"
        border
      >
        <el-descriptions-item label-class-name="descriptions_item_label">
          <template #label>
            <div class="cell-item">
              <el-icon>
                <Lock />
              </el-icon>
              密码
            </div>
          </template>
          <div class="setting_content">
            <span>****************</span>
            <span class="setting_operaton" @click="pwdDialogVisible = true">
              修改密码
            </span>
          </div>
        </el-descriptions-item>
        <el-descriptions-item>
          <template #label>
            <div class="cell-item">
              <el-icon>
                <Message />
              </el-icon>
              邮箱
            </div>
          </template>
          <div class="setting_content">
            <span>{{ userFormData.email }}</span>
            <span class="setting_operaton" @click="emailDialogVisible = true">
              修改邮箱
            </span>
          </div>
        </el-descriptions-item>
      </el-descriptions>
    </el-card>

    <el-dialog v-model="pwdDialogVisible" title="密码设置">
      <el-form
        ref="pwdForms"
        :inline="true"
        :model="pwdForm"
        :rules="pwdrules"
        label-position="top"
        label-width="85px"
        style="width: 300px; margin: 68px auto"
      >
        <el-form-item prop="password" style="width: 90%">
          <el-input
            show-password
            size="large"
            type="password"
            v-model="pwdForm.password"
            placeholder="请输入旧密码"
            prefix-icon="Lock"
          />
        </el-form-item>
        <el-form-item prop="newPassword" style="width: 90%">
          <el-input
            show-password
            size="large"
            type="password"
            v-model="pwdForm.newPassword"
            placeholder="请输入新密码"
            prefix-icon="Lock"
          />
        </el-form-item>
        <el-form-item prop="resetPassword" style="width: 90%">
          <el-input
            show-password
            size="large"
            type="password"
            v-model="pwdForm.resetPassword"
            placeholder="请重新输入新密码"
            prefix-icon="Lock"
          />
        </el-form-item>
        <el-form-item style="width: 90%">
          <span class="dialog-footer">
            <el-button @click="pwdDialogVisible = false">取消</el-button>
            <el-button type="primary" @click="updatePwd()">更新密码</el-button>
          </span>
        </el-form-item>
      </el-form>
    </el-dialog>

    <el-dialog v-model="emailDialogVisible" title="邮箱设置">
      <el-form
        v-if="!isUpdate"
        ref="emailForms"
        :inline="true"
        :model="oldEmailForm"
        :rules="rules"
        label-position="top"
        label-width="85px"
        style="width: 300px; margin: 68px auto"
      >
        <el-form-item prop="email" style="width: 90%">
          <el-input
            type="email"
            v-model="userFormData.email"
            disabled
            size="large"
            placeholder="请输入邮箱"
            prefix-icon="User"
          />
        </el-form-item>
        <el-form-item prop="captcha" style="width: 90%">
          <el-input
            v-model="oldEmailForm.captcha"
            size="large"
            placeholder="请输入验证码"
            prefix-icon="CircleCheck"
          >
            <template #append>
              <el-button :disabled="countdown > 0" @click="getOldCaptcha()">
                {{ countdown > 0 ? `${countdown}秒后重新获取` : '获取验证码' }}
              </el-button>
            </template>
          </el-input>
        </el-form-item>
        <el-form-item style="width: 90%">
          <span class="dialog-footer">
            <el-button @click="emailDialogVisible = false">取消</el-button>
            <el-button type="primary" @click="verifyOldEmail()">
              校验旧邮箱
            </el-button>
          </span>
        </el-form-item>
      </el-form>
      <el-form
        v-else
        ref="emailForms"
        :inline="true"
        :model="newEmailForm"
        :rules="rules"
        label-position="top"
        label-width="85px"
        style="width: 300px; margin: 68px auto"
      >
        <el-form-item prop="newEmail" style="width: 90%">
          <el-input
            type="email"
            v-model="newEmailForm.newEmail"
            size="large"
            placeholder="请输入邮箱"
            prefix-icon="User"
          />
        </el-form-item>
        <el-form-item prop="captcha" style="width: 90%">
          <el-input
            v-model="newEmailForm.captcha"
            size="large"
            placeholder="请输入验证码"
            prefix-icon="CircleCheck"
          >
            <template #append>
              <el-button :disabled="countdown > 0" @click="getNewCaptcha()">
                {{ countdown > 0 ? `${countdown}秒后重新获取` : '获取验证码' }}
              </el-button>
            </template>
          </el-input>
        </el-form-item>
        <el-form-item style="width: 90%">
          <span class="dialog-footer">
            <el-button @click="emailDialogVisible = false">取消</el-button>
            <el-button type="primary" @click="updateEmail()">
              更新邮箱
            </el-button>
          </span>
        </el-form-item>
      </el-form>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { onMounted, reactive, ref } from 'vue'
import {
  reqMyUserInfo,
  reqUpdateUserAvatar,
  reqUpdateUserSign,
} from '@/api/user'
import { UserInfoRes } from '@/api/user/type'
import { ElMessage, UploadProps } from 'element-plus'
import { Upload_API } from '@/api/upload'
import { GET_TOKEN } from '@/utils/token'
import { UploadImageRes } from '@/api/upload/type'
import { UserLoginByEmailParams } from '@/api/auth/type'
import {
  reqChangeEmail,
  reqChangePwd,
  reqGetNewEmailCaptcha,
  reqGetOldEmailCaptcha,
  reqVrifyOldEmail,
} from '@/api/auth'

onMounted(async () => {
  await getMineUserInfo()
})

const userFormData = ref<UserInfoRes>({
  id: 0,
  name: '',
  username: '',
  email: '',
  avatar: '',
  sign: '',
  sex: 1,
  roles: [],
  roleIds: [],
  status: 1,
  deleted: 0,
  createTime: '',
  updateTime: '',
})

const headerObj = {
  Authorization: GET_TOKEN(),
}

const isSignEdit = ref(false)
const updateSignText = ref('')

const emailForms = ref()
const emailDialogVisible = ref(false)
const pwdDialogVisible = ref(false)
const isUpdate = ref(false)
let oldEmailForm: UserLoginByEmailParams = reactive({
  email: '',
  captcha: '',
})
let newEmailForm = reactive({
  email: '',
  newEmail: '',
  captcha: '',
})
const countdown = ref(0)

const pwdForms = ref()
const pwdForm = reactive({
  username: '',
  password: '',
  newPassword: '',
  resetPassword: '',
})

const rules: any = reactive({
  email: [
    {
      required: true,
      type: 'email',
      message: '输入正确的邮箱',
      trigger: 'blur',
    },
  ],
  captcha: [
    { required: true, message: '输入验证码', trigger: 'blur' },
    { min: 6, max: 6, message: '必须为六位验证码', trigger: 'blur' },
  ],
})

const openEditSign = () => {
  isSignEdit.value = !isSignEdit.value
  updateSignText.value = userFormData.value.sign
}

const checkPassword = (rule: any, value: any, callback: any) => {
  if (value.length < 6 || value.length > 16) {
    return callback(new Error('请输入6位到16位的密码'))
  } else {
    callback()
  }
}

const checkResetPassword = (rule: any, value: any, callback: any) => {
  if (value.length != pwdForm.newPassword) {
    return callback(new Error('密码不一致'))
  } else {
    callback()
  }
}

const pwdrules = reactive({
  newPassword: [{ validator: checkPassword, trigger: 'blur' }],
  password: [{ validator: checkPassword, trigger: 'blur' }],
  resetPassword: [{ validator: checkResetPassword, trigger: 'blur' }],
})

const getMineUserInfo = async () => {
  try {
    const { data } = await reqMyUserInfo()
    userFormData.value = data
    pwdForm.username = data.username
  } catch (error) {
    ElMessage.error((error as Error).message)
  }
}

const getOldCaptcha = async () => {
  try {
    const { message } = await reqGetOldEmailCaptcha(userFormData.value.email)
    startTimer()
    ElMessage.success(message)
  } catch (error) {
    ElMessage({
      type: 'error',
      message: (error as Error).message,
    })
  }
}

const verifyOldEmail = async () => {
  await emailForms.value.validateField('captcha')
  try {
    oldEmailForm.email = userFormData.value.email
    const { message } = await reqVrifyOldEmail(oldEmailForm)
    countdown.value = 0
    isUpdate.value = true
    ElMessage.success(message)
  } catch (error) {
    ElMessage({
      type: 'error',
      message: (error as Error).message,
    })
  }
}

const getNewCaptcha = async () => {
  await emailForms.value.validateField('newEmail')
  try {
    const { message } = await reqGetNewEmailCaptcha(newEmailForm.newEmail)
    startTimer()
    ElMessage.success(message)
  } catch (error) {
    ElMessage({
      type: 'error',
      message: (error as Error).message,
    })
  }
}

const updateEmail = async () => {
  await emailForms.value.validate()
  try {
    newEmailForm.email = userFormData.value.email
    const { message } = await reqChangeEmail(newEmailForm)
    isUpdate.value = false
    emailDialogVisible.value = false
    ElMessage.success(message)
  } catch (error) {
    ElMessage({
      type: 'error',
      message: (error as Error).message,
    })
  }
}

const updatePwd = async () => {
  await pwdForms.value.validate()
  try {
    const { message } = await reqChangePwd(pwdForm)
    pwdDialogVisible.value = false
    ElMessage.success(message)
  } catch (error) {
    ElMessage({
      type: 'error',
      message: (error as Error).message,
    })
  }
}

const startTimer = () => {
  countdown.value = 60

  const timer = setInterval(() => {
    countdown.value--

    if (countdown.value === 0) {
      clearInterval(timer)
    }
  }, 1000)
}

const updateSign = async () => {
  try {
    let signData = {
      content: updateSignText.value,
    }
    const { message } = await reqUpdateUserSign(signData)
    isSignEdit.value = !isSignEdit.value
    userFormData.value.sign = signData.content
    ElMessage.success(message)
  } catch (error) {
    ElMessage.error((error as Error).message)
  }
}

const handleAvatarSuccess: UploadProps['onSuccess'] = (response) => {
  const data: UploadImageRes = response.data
  userFormData.value.avatar = data.imageUrl
  updateUserAvatar(userFormData.value.avatar)
}

const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
  if (rawFile.type !== 'image/png' && rawFile.type !== 'image/jpeg') {
    ElMessage.error('上传的图片格式必须是png或jpg！')
    return false
  } else if (rawFile.size / 1024 / 1024 > 2) {
    ElMessage.error('图片大小不能超过2MB！')
    return false
  }
  return true
}

const updateUserAvatar = async (avatar: string) => {
  try {
    let avatarData = {
      content: avatar,
    }
    const { message } = await reqUpdateUserAvatar(avatarData)
    ElMessage.success(message)
  } catch (error) {
    ElMessage.error((error as Error).message)
  }
}
</script>
<style scoped lang="scss">
.personal_container {
  width: 100%;

  .personal_card {
    margin-top: 15px;
    border-radius: 10px;
    margin-left: 5%;
    width: 90%;
    padding: 0px 20px;
    border: 1px solid #7e7e7e83;

    .card-header {
      display: flex;
      align-items: center;

      .img_style {
        height: 120px;
        width: 120px;
        border-radius: 50%;
      }

      .user_info {
        position: relative;
        margin-left: 40px;

        .user_nickname {
          padding: 5px;
          font-size: 20px;
          font-weight: 600;
        }

        .user_role {
          margin-top: 5px;
          padding: 5px;
          font-size: 16px;
          font-weight: 400;
        }

        .user_sign {
          padding: 5px;
          font-size: 16px;
          font-weight: 400;

          .sign_edit {
            cursor: pointer;
            margin-left: 6px;
          }

          .sign_edit:hover {
            color: var(--el-color-primary);
          }
        }
      }
    }

    .card_descriptions {
      width: 96%;
      margin-left: 2%;

      .setting_content {
        display: flex;
        justify-content: space-between;

        .setting_operaton {
          cursor: pointer;
          margin-right: 10px;
        }

        .setting_operaton:hover {
          color: var(--el-color-primary);
        }
      }
    }
  }
}

.cell-item {
  display: flex;
  align-items: center;
}

.avatar-uploader .avatar {
  width: 128px;
  height: 128px;
  display: block;
}
</style>

<style lang="scss">
.el-descriptions__body .el-descriptions__table {
  width: 86%;
  margin-left: 7%;
}

.descriptions_item_label {
  width: 15%;
  min-width: 105px;
  align-items: center;
}
</style>
